#-*- coding: utf-8 -*-
import os
import shutil
import sys
import codecs

import wx
import wx.stc

import tools
import tex
import actions
from misc import config
from editor import TexEditor
from editimage import EditImageDlg

version = "1.5"


class ResultPanel (wx.Panel):
	"""Панель с просмотром конечного результата"""
	def __init__(self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, \
							size = wx.DefaultSize, style = wx.TAB_TRAVERSAL, name = "panel"):
		wx.Panel.__init__(self, parent, id, pos, size, style, name)
		
		self.image = None
		self.backColor = wx.WHITE
		
		self.SetSize ( (-1, 300) )
		self.SetBackgroundColour (self.backColor)
		
		self.Bind (wx.EVT_PAINT, self.onPaint )
	
	def getImage (self):
		return self.image
	
	def onPaint (self, event):
		dc = wx.PaintDC (self)
		if self.image:
			bmp = wx.BitmapFromImage (self.image)
			dc.DrawBitmap (bmp, 8, 8, True)
		else:
			dc.Clear()
	
	def update (self, image):
		self.image = image
		self.Refresh(True)


class MainWnd(wx.Frame):
	def __init__(self, *args, **kwds):
		kwds["style"] = wx.DEFAULT_FRAME_STYLE
		wx.Frame.__init__(self, *args, **kwds)
		
		self.SAVE_IMAGE = wx.NewId()
		self.SAVE_TEX = wx.NewId()
		self.OPEN_TEX = wx.NewId()
		self.UPDATE_VIEW = wx.NewId()
		self.ADD_TOOL_GROUP = wx.NewId()
		self.ADD_TOOL_ITEM = wx.NewId()
		self.ABOUT = wx.NewId()
		
		self.SetAutoLayout (True)
		self.texCompiler = tex.MimeTex ("mimetex")
		self.makeGui()
		
		self.SetSize ( config.instance().windowSize )
		
		self.Move ( config.instance().windowPos )
		self.icon = wx.Icon("images/texgui_16.ico", wx.BITMAP_TYPE_ICO)
		
		self.SetIcon(self.icon)
		
		self.usersbase = tools.ToolsBase (self, self.toolspanel)
		self.usersbase.Load ()
		
		self.imageUpdateTimer = wx.Timer(self)

		# Нужно ли обновлять картинку?
		self._needUpdate = False

		self.Bind (wx.stc.EVT_STC_CHANGE, self.onChange, self.editor)
		self.Bind (wx.EVT_TIMER, self.onTimer, self.imageUpdateTimer)
		self.Bind (wx.EVT_CLOSE, self.onClose)
		#self.Bind (wx.EVT_IDLE, self.onIdle)
	
	def onClose (self, event):
		self.usersbase.Save ()
		
		self.imageUpdateTimer.Stop()
		
		config.instance().windowPos = self.GetPosition()
		config.instance().windowSize = self.GetSize()
		
		try:
			config.instance().save()
		except IOError:
			wx.MessageBox (u"Не могу сохранить настройки", \
				u"Ошибка", wx.OK | wx.ICON_ERROR)
			
		self.Destroy()
	
	def onChange (self, event):
		self.imageUpdateTimer.Start(800, oneShot = True)
		self._needUpdate = True
		pass
	
	def onTimer (self, event):
		self.updateImage()

	def onIdle (self, event):
		if self._needUpdate:
			self.updateImage()
			self._needUpdate = False
	
	def makeMenu (self):
		"""
		Создать меню
		"""
		self.mainMenu = wx.MenuBar ()
		
		# Файл
		fileMenu = wx.Menu()

		fileMenu.Append (self.OPEN_TEX, u"&Открыть...\tCtrl+O")
		self.Bind (wx.EVT_MENU, self.onOpenTex, id = self.OPEN_TEX)

		fileMenu.Append (self.SAVE_TEX, u"&Сохранить...\tCtrl+S")
		self.Bind (wx.EVT_MENU, self.onSaveTex, id = self.SAVE_TEX)

		fileMenu.Append (self.SAVE_IMAGE, u"&Экспорт в изображение...\tCtrl+E")
		self.Bind (wx.EVT_MENU, self.onSaveImage, id = self.SAVE_IMAGE)

		self.mainMenu.Append (fileMenu, u"&Файл")

		# Вид
		viewMenu = wx.Menu()
		viewMenu.Append (self.UPDATE_VIEW, u"&Обновить\tF5")
		self.Bind (wx.EVT_MENU, self.onUpdateView, id = self.UPDATE_VIEW)

		self.mainMenu.Append (viewMenu, u"&Вид")

		# Инструменты
		toolsMenu = wx.Menu()
		toolsMenu.Append (self.ADD_TOOL_ITEM, u"&Добавить элемент...\tCtrl+Ins")
		toolsMenu.Append (self.ADD_TOOL_GROUP, u"Д&обавить группу элементов...\tCtrl+G")
		
		self.Bind (wx.EVT_MENU, self.onAddItem, id = self.ADD_TOOL_ITEM)
		self.Bind (wx.EVT_MENU, self.onAddGroup, id = self.ADD_TOOL_GROUP)
		
		self.mainMenu.Append (toolsMenu, u"&Инструменты")
				
		# Справка
		helpMenu = wx.Menu()
		helpMenu.Append (self.ABOUT, u"&О программе...\tF1")
		self.Bind (wx.EVT_MENU, self.onAbout, id = self.ABOUT)
		
		self.mainMenu.Append (helpMenu, u"&Справка")
		
		self.SetMenuBar (self.mainMenu)

	def onSaveTex (self, event):
		"""
		Сохранить введенный текст в текстовый файл (tex)
		"""
		dlg = wx.FileDialog (self,
				wildcard = "*.tex|*.tex|Все файлы|*.*",
				style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

		if dlg.ShowModal () == wx.ID_OK:
			fname = os.path.join (dlg.GetDirectory(), dlg.GetFilename())
			text = self.editor.GetText()

			try:
				fp = open (fname, "wb")
				fp.write (text)
				fp.close()
			except IOError:
				wx.MessageBox (u"Невозможно сохранить файл " + fname, \
					u"Ошибка", wx.OK | wx.ICON_ERROR)
	
		dlg.Destroy()
	
	def onOpenTex (self, event):
		"""
		Открыть текстовый файл
		"""
		dlg = wx.FileDialog (self,
				wildcard = "*.tex|*.tex|Все файлы|*.*",
				style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

		if dlg.ShowModal () == wx.ID_OK:
			fname = os.path.join (dlg.GetDirectory(), dlg.GetFilename())

			try:
				fp = open (fname, "rb")
				text = fp.read()
				fp.close()

				self.editor.SetText (text)
			except IOError:
				wx.MessageBox (u"Невозможно сохранить файл " + fname, \
					u"Ошибка", wx.OK | wx.ICON_ERROR)
	
		dlg.Destroy()

	def onUpdateView (self, event):
		self.updateImage()

	def onAbout (self, event):
		info = wx.AboutDialogInfo()
		info.AddDeveloper (u"Ильин Е. В. (aka Jenyay)")
		info.AddDeveloper (u"Жиров В. В. (aka vvzh)")
		info.SetCopyright (u"(c) 2008-2010 Ильин Е. В. (aka Jenyay)")
		info.SetName (u"TeXGui")
		info.SetDescription (u"Программа для создания формул в формате TeX.\nРаботает на движке mimeTeX.")

		# Version:
		info.SetVersion (version)
		info.SetWebSite ("http://jenyay.net")
		icon = wx.Icon(os.path.join (os.path.dirname(sys.argv[0]), \
										u"images/texgui.ico"), wx.BITMAP_TYPE_ICO)
		info.SetIcon (icon)
		
		wx.AboutBox(info)
	
	def onAddGroup (self, event):
		dlg = tools.NewToolsGroupDlg (self, self.editor.GetText())
		dlg.Center()
		if dlg.ShowModal() == wx.ID_OK:
			name = dlg.GetGroupName()
			package = dlg.GetPackageName()
			self.toolspanel.AddPage (name, package + ".tools")
		
		dlg.Destroy()
	
	def onAddItem (self, event):
		page = self.toolspanel.GetCurrentPage()
		#image = self.previewpanel.getImage()
		
		text_editor = self.editor.GetText()
		#pos = self.editor.GetCurrentPos()
		
		dlg = tools.ToolsItemParamsDlg(self, text_editor)
		
		if dlg.ShowModal() == wx.ID_OK:
			text = dlg.GetItemTex()
			pos = dlg.GetPosition()
			image = dlg.GetButtonImage()
				
			item = page.AddItem (text, pos, image)
			self.Bind (wx.EVT_BUTTON, self.onToolsClick, id = item.id)
		
		dlg.Destroy()
	
	def onToolsClick (self, event):
		page = self.toolspanel.GetCurrentPage()
		item = page.GetItem (event.GetId())
		
		text = item.text
		self.editor.AddText(text)
		
		pos = self.editor.GetCurrentPos()
		
		self.editor.GotoPos (pos - len (text) + item.cursorPosition )
		self.editor.SetFocus()
	
	def onSaveImage (self, event):
		self.updateImage()

		dlg = wx.FileDialog (self,
				wildcard = "GIF (*.gif)|*.gif|PNG (*.png)|*.png|BMP (*.bmp)|*.bmp|JPEG (*.jpg)|*.jpg|TIFF (*.tif)|*.tif",
				style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

		# Диалог выбора файла
		if dlg.ShowModal () == wx.ID_OK:
			fname = os.path.join (dlg.GetDirectory(), dlg.GetFilename())

			text = self.editor.GetText()
			editDlg = EditImageDlg (self, text)

			# Диалог постобработки изображения
			if editDlg.ShowModal() == wx.ID_OK:
				previewFname = self.texCompiler.getResultFilename()
				actions.saveImage (fname, editDlg.image, previewFname)

			editDlg.Destroy()
	
		dlg.Destroy()
	
	def makeGui (self):
		mainsizer = wx.FlexGridSizer(rows = 3, cols = 1)
		mainsizer.AddGrowableCol (0)
		mainsizer.AddGrowableRow(1)
		
		# Инструменты
		self.toolspanel = tools.ToolsPanel (self)
		mainsizer.Add (self.toolspanel, 0, wx.EXPAND)
		
		self.splitPanel = wx.SplitterWindow (self, wx.ID_ANY)
		
		# Редактор
		self.editor = TexEditor(self.splitPanel)
		self.editor.SetMinSize ( (-1, 150) )

		# Панель для просмотра
		self.previewpanel = ResultPanel (self.splitPanel)
		self.previewpanel.SetMinSize ( (-1, 150) )

		self.splitPanel.SplitHorizontally (self.editor, self.previewpanel)
		mainsizer.Add (self.splitPanel, 0, wx.EXPAND)
	
		self.SetSizer (mainsizer)
		self.Layout()
		
		self.SetTitle ("TeXGui")
		self.makeMenu()
	
	def updateImage(self):
		image = self.texCompiler.compile (self.editor.GetText(), False)
		self.previewpanel.update (image)


if __name__ == "__main__":
	app = wx.PySimpleApp(0)
	wx.InitAllImageHandlers()
	texgui = MainWnd(None, -1, "")
	app.SetTopWindow(texgui)
	texgui.Show()
	app.MainLoop()
